/*
 * app_task.c
 *
 *  Created on: Jan 31, 2024
 *      Author: Administrator
 */
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"

#include "tim.h"

#include "app_task.h"
#include "app_store.h"
#include "dlom2_sensor.h"
#
#include "pid_pmeasure.h"
#include "data_convert.h"

#include <string.h>
#include <stdio.h>
#include <math.h>
#include <stdint.h>
#include <stdbool.h>

pid_pmeasure_ctrl_t *pid_ctrl_ptr = NULL;

void set_pwm_output_enable() {
	HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
	HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_2);
}
void set_pwm_output(uint16_t value) {

	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1, value);
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_2, value);
}
//低电平有效
void set_pwm_dir_output(uint8_t dir) {

	if (dir == 0) {
		HAL_GPIO_WritePin(Dir_Forward_PIN_GPIO_Port, Dir_Forward_PIN_Pin,
				RESET);
		HAL_GPIO_WritePin(Dir_Reverse_PIN_GPIO_Port, Dir_Reverse_PIN_Pin, SET);

		HAL_GPIO_WritePin(PWM_DIR_FORWARD_PIN_GPIO_Port,
		PWM_DIR_FORWARD_PIN_Pin, RESET);
		HAL_GPIO_WritePin(PWM_DIR_REVERSE_PIN_GPIO_Port,
		PWM_DIR_REVERSE_PIN_Pin, SET);
	} else

	{
		HAL_GPIO_WritePin(Dir_Forward_PIN_GPIO_Port, Dir_Forward_PIN_Pin, SET);
		HAL_GPIO_WritePin(Dir_Reverse_PIN_GPIO_Port, Dir_Reverse_PIN_Pin,
				RESET);

		HAL_GPIO_WritePin(PWM_DIR_FORWARD_PIN_GPIO_Port,
		PWM_DIR_FORWARD_PIN_Pin, SET);
		HAL_GPIO_WritePin(PWM_DIR_REVERSE_PIN_GPIO_Port,
		PWM_DIR_REVERSE_PIN_Pin, RESET);
	}
}

void app_task_pid_task_init() {

	pid_ctrl_ptr = pid_pmeasure_ctrl_new(&pid_cache.input_value,
			&pid_cache.foutput_value, &pid_cache.sv, pid_cache.kp, pid_cache.ki,
			pid_cache.kd, P_ON_M, DIRECT);

	pid_pmeasure_ctrl_set_model(pid_ctrl_ptr, MANUAL);

	pid_pmeasure_ctrl_set_output_limits(pid_ctrl_ptr, pid_cache.out_min,
			pid_cache.out_max);

	pid_pmeasure_ctrl_set_controller_direction(pid_ctrl_ptr, DIRECT);

	pid_pmeasure_ctrl_set_sampletime(pid_ctrl_ptr, pid_cache.delay_ms);

	set_pwm_output_enable();
	set_pwm_dir_output(pid_cache.output_dir);
	set_pwm_output(pid_cache.output_value);

}

void app_task_excute_output() {

#if APP_TASK_DEBUG
	printf("pid task excute \r\n");
#endif

	pid_cache.input_value = dlom2_sensor_value.temperatureValue;

	//大于目标温度 ：制冷
	if (pid_cache.input_value >= pid_cache.sv) {
		pid_pmeasure_ctrl_set_controller_direction(pid_ctrl_ptr, REVERSE);
		pid_cache.output_dir = REVERSE;

	} else

	{
		//小于目标温度：加热
		pid_pmeasure_ctrl_set_controller_direction(pid_ctrl_ptr, DIRECT);
		pid_cache.output_dir = DIRECT;

	}

	bool ret = pid_pmeasure_ctrl_compute(pid_ctrl_ptr);
	if (!ret)
		pid_cache.foutput_value = 0;

	pid_cache.output_value = (uint16_t) (pid_cache.foutput_value);

	set_pwm_dir_output(pid_cache.output_dir);
	set_pwm_output(pid_cache.output_value);

	printf("pwm output:%d \r\n", pid_cache.output_value);
}

void app_task_check_update_init() {

	app_store_set_pid_param_to_slave();

}
void app_task_update_pid_param() {
	char pbuf[20] = { 0 };
	py_f2s4printf(pbuf, pid_cache.kp, 3);
	printf("save: %s \r\n", pbuf);

	if (app_store_get_pid_ctrl_state() == as_yes) {
		pid_pmeasure_ctrl_set_model(pid_ctrl_ptr, AUTOMATIC);

	} else {
		pid_pmeasure_ctrl_set_model(pid_ctrl_ptr, MANUAL);
	}

	pid_pmeasure_ctrl_set_output_limits(pid_ctrl_ptr, pid_cache.out_min,
			pid_cache.out_max);

	int P_ON = P_ON_M;

	if (app_store_get_pid_no_measure_state() == as_yes) {
		P_ON = P_ON_E;
	}
	pid_pmeasure_ctrl_set_tunings(pid_ctrl_ptr, pid_cache.kp, pid_cache.ki,
			pid_cache.kd, P_ON);

	pid_pmeasure_ctrl_set_sampletime(pid_ctrl_ptr, pid_cache.delay_ms);
}
static void app_task_check_calibration() {

	if (app_store_get__maintenance_state() == as_yes) {
		dlom2_set_maintenance_state_enable();
		app_store_set__maintenance_state(as_no);
	}
	if (app_store_get_calibration_density_state() == as_yes) {
		dlom2_set_calibration_density_state_enable();
		app_store_set_calibration_density_state(as_no);
	}
	if (app_store_get_calibration_viscosity_state() == as_yes) {
		dlom2_set_calibration_viscosity_state_enable();
		app_store_set_calibration_density_state(as_no);
	}
}

static void app_task_check_save_param() {

	if (app_store_get_save_param_state() == as_yes) {

		app_store_set_pid_param_from_slave();
		app_task_update_pid_param();
		app_task_check_calibration();

		app_store_set_save_param_state(as_no);
	}
}

static void app_task_check_stabilize_value() {

	float diff = fabs(pid_cache.sv - pid_cache.input_value);

	if (diff <= 0.1) {
		app_store_set_stabilize_value_state(as_yes);
	} else

	{
		app_store_set_stabilize_value_state(as_no);
	}
}
static void app_task_check_pwm_output_dir() {

	app_store_set_pwm_output_value(pid_cache.output_value);
	app_store_set_pwm_output_dir(pid_cache.output_dir);

}
void app_task_update_poll() {

	//read slave
#if APP_TASK_DEBUG
	printf("update task poll \r\n");
#endif
	app_task_check_save_param();
	osDelay(100);
	app_task_check_stabilize_value();
	osDelay(100);
	app_task_check_pwm_output_dir();
	osDelay(100);

}

